package dbsvc

import (
	"server/application/constant/enums"
	"server/application/db/dbinit"
	"server/application/db/system/columns"
	"server/application/db/system/dbdic"
	"server/application/db/system/dbdto"
	"server/application/db/system/entity"
	"server/application/db/system/repository"
	"server/pkg/mylog"
	"server/pkg/where"
	"server/setting"
	"strconv"
)

// SysDictionaryCreate 创建
func SysDictionaryCreate(dtoCreate *dbdto.SysDictionaryCreate) (*dbdto.SysDictionaryInfo, error) {
	return repository.Create[
		entity.SysDictionary, dbdto.SysDictionaryCreate, dbdto.SysDictionaryInfo,
	](dtoCreate)
}

// SysDictionaryFindOneById 查找
func SysDictionaryFindOneById(id uint) (*dbdto.SysDictionaryInfo, error) {
	wheres := where.FormatOne("id", "=", id)
	return repository.FindOne[
		entity.SysDictionary, dbdto.SysDictionaryInfo,
	](wheres, false)
}

// SysDictionaryFindList 查找列表
func SysDictionaryFindList(wheres []*where.Condition, extra *where.Extra) ([]*dbdto.SysDictionaryInfo, error) {
	return repository.FindList[
		entity.SysDictionary, dbdto.SysDictionaryInfo](wheres, extra, false)
}

// SysDictionarySearch 搜索
func SysDictionarySearch(wheres []*where.Condition, extra *where.Extra) ([]*dbdto.SysDictionaryInfo, int64) {
	total, err := SysDictionaryGetTotal(wheres)
	list := make([]*dbdto.SysDictionaryInfo, 0)
	if err != nil || total <= 0 {
		return list, 0
	}
	list, err = SysDictionaryFindList(wheres, extra)
	return list, total
}

// SysDictionaryUpdate 更新，字段可按规则传入，传入那个修改哪个
func SysDictionaryUpdate(wheres []*where.Condition, dtoUpdate *dbdto.SysDictionaryUpdate, columnsCfg ...string) error {
	return repository.Update[
		entity.SysDictionary, dbdto.SysDictionaryUpdate](wheres, dtoUpdate, columnsCfg...)
}

// SysDictionaryDelete 删除（deleted_at存在则是软删除）
func SysDictionaryDelete(wheres []*where.Condition) error {
	return repository.Delete[entity.SysDictionary](wheres, setting.UseSoftDelete)
}

// SysDictionaryGetTotal 获取总数
func SysDictionaryGetTotal(wheres []*where.Condition) (int64, error) {
	return repository.GetTotal[entity.SysDictionary](wheres)
}

// SysDictionaryGetOptionsBySql 通过sql查询来获取options列表
// sql example : "SELECT username as label, id as value from sys_users WHERE 1"
func SysDictionaryGetOptionsBySql(sql string) ([]dbdic.DicOption, error) {
	var options []dbdic.DicOption
	db := dbinit.GetDbInstance()
	rows, err := db.Raw(sql).Rows()
	if err != nil {
		return options, err
		// 错误处理
	}
	defer rows.Close()

	for rows.Next() {
		var option dbdic.DicOption
		var valueBytes []byte // 临时变量
		err := rows.Scan(&valueBytes, &option.Label)
		if err != nil {
			return options, err
		}
		option.Value = string(valueBytes) // 将字节切片转换为字符串
		options = append(options, option)
	}

	return options, nil
}

// SysDictionaryFilter 二次过滤,尝试将其转换成整型
func SysDictionaryFilter(oldOptions []dbdic.DicOption, targetType string) []dbdic.DicOption {
	var options []dbdic.DicOption
	for i := 0; i < len(oldOptions); i++ {
		item := oldOptions[i]
		val := item.Value
		if strVal, ok := val.(string); ok { //默认都是string
			option := dbdic.DicOption{
				Label: item.Label,
			}
			switch targetType {
			case enums.DicDataTypeString:
				option.Value = strVal
				break
			case enums.DicDataTypeNumber:
				option.Value, _ = strconv.Atoi(strVal)
				break
			}
			options = append(options, option)
		} else {
			options = append(options, dbdic.DicOption{
				Label: item.Label,
				Value: val, //使用原始值
			})
		}
	}
	return options
}

// SysDictionaryGetString 根据key获取一个字符串类型的字典
func SysDictionaryGetString(key string) string {
	info, err := SysDictionaryFindOne(where.Format(
		where.Opt(columns.SysDictionaryDicKey, "=", key),
		where.Opt(columns.SysDictionaryDicValueType, "=", enums.DicValueTypeString),
	),
	)
	if err != nil {
		mylog.Error(err.Error())
		return ""
	}
	if info != nil && info.ID > 0 {
		return info.DicValue
	}
	return ""
}

func SysDictionarySetString(key string, val string) bool {
	//不管有没有 先删除
	err := SysDictionaryDelete(where.Format(
		where.Opt(columns.SysDictionaryDicKey, "=", key),
		where.Opt(columns.SysDictionaryDicValueType, "=", enums.DicValueTypeString),
	))
	if err != nil {
		return false
	}

	create, err := SysDictionaryCreate(&dbdto.SysDictionaryCreate{
		DicValueType:  enums.DicValueTypeString,
		ValueDataType: enums.DicDataTypeString,
		DicKey:        key,
		DicValue:      val,
		Description:   "by setting",
		IsActive:      true,
		DicSort:       0,
	})
	if err != nil {
		return false
	}
	if create == nil || create.ID == 0 {
		return false
	}
	return true
}

// SysDictionaryFindOne 查找1个
func SysDictionaryFindOne(wheres []*where.Condition) (*dbdto.SysDictionaryInfo, error) {
	return repository.FindOne[
		entity.SysDictionary, dbdto.SysDictionaryInfo,
	](wheres, false)
}
